﻿namespace EFS.RC.CC.Tools.Functions
{
	/// <summary>
	/// Termination
	/// </summary>
	class Termination : EFS.Common.ISelfDescriptor
	{
		#region Composition

		/// Conference participant
		private EFS.Common.ISelfDescriptor owner = null;

		#endregion

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="conversation"></param>
		/// <param name="remoteEndpoint"></param>
		public Termination(EFS.Common.ISelfDescriptor owner)
		{
			// log
			EFS.EventLog.Log.LogInfo("EFS.RC.CC.Tools.Functions.Termination:ctor");

			// check
			EFS.Common.Verify.Reference(owner, "owner");

			// set
			this.owner = owner;
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public System.String Describe()
		{
			return System.String.Format("EFS.RC.CC.Tools.Functions.Termination [{0}]", owner.Describe());
		}

		/// <summary>
		/// Terminate conversation
		/// </summary>
		/// <param name="conversation"></param>
		/// <param name="asyncResultMethod"></param>
		public void Terminate(Microsoft.Rtc.Collaboration.Conversation conversation, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != conversation && conversation.State != Microsoft.Rtc.Collaboration.ConversationState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						conversation.BeginTerminate(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						conversation.BeginTerminate(EndTerminateConversation, conversation);
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate conversation
		/// </summary>
		/// <param name="conversation"></param>
		/// <param name="asyncResultMethod"></param>
		public void TerminateConference(Microsoft.Rtc.Collaboration.Conversation conversation, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != conversation && conversation.State != Microsoft.Rtc.Collaboration.ConversationState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						conversation.ConferenceSession.BeginTerminateConference(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						conversation.ConferenceSession.BeginTerminateConference(EndTerminateConference, conversation);
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate call
		/// </summary>
		/// <param name="instantMessagingCall"></param>
		/// <param name="asyncResultMethod"></param>
		public void Terminate(Microsoft.Rtc.Collaboration.InstantMessagingCall instantMessagingCall, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != instantMessagingCall && instantMessagingCall.State != Microsoft.Rtc.Collaboration.CallState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						instantMessagingCall.BeginTerminate(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						instantMessagingCall.BeginTerminate(EndTerminateInstantMessagingCall, instantMessagingCall);
					}
				}
			}
			catch (System.Exception ex)
			{ 
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate call
		/// </summary>
		/// <param name="audioVideoCall"></param>
		/// <param name="asyncResultMethod"></param>
		public void Terminate(Microsoft.Rtc.Collaboration.AudioVideo.AudioVideoCall audioVideoCall, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != audioVideoCall && audioVideoCall.State != Microsoft.Rtc.Collaboration.CallState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						audioVideoCall.BeginTerminate(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						audioVideoCall.BeginTerminate(EndTerminateAudioVideoCall, audioVideoCall);
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate context chanel
		/// </summary>
		/// <param name="conversationContextChannel"></param>
		/// <param name="asyncResultMethod"></param>
		public void Terminate(Microsoft.Rtc.Collaboration.ConversationContextChannel conversationContextChannel, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != conversationContextChannel && conversationContextChannel.State != Microsoft.Rtc.Collaboration.ConversationContextChannelState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						conversationContextChannel.BeginTerminate(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						conversationContextChannel.BeginTerminate(EndTerminateConversationContextChannel, conversationContextChannel);
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate b2b call
		/// </summary>
		/// <param name="conversationContextChannel"></param>
		/// <param name="asyncResultMethod"></param>
		public void Terminate(Microsoft.Rtc.Collaboration.BackToBackCall b2bCall, EFS.Common.Async.AsyncResult.StateDelegate.AsyncResultMethod asyncResultMethod = null)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != b2bCall && b2bCall.State != Microsoft.Rtc.Collaboration.BackToBackCallState.Terminated)
				{
					// check provided method
					if (null != asyncResultMethod)
					{
						// terminate conversation
						b2bCall.BeginTerminate(
							EFS.Common.Async.AsyncResult.StateDelegate.End,
							EFS.Common.Async.AsyncResult.StateDelegate.State(asyncResultMethod));
					}
					else
					{
						// terminate conversation
						b2bCall.BeginTerminate(EndTerminateBackToBackCall, b2bCall);
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Close source
		/// </summary>
		/// <param name="fileSource"></param>
		public void Close(Microsoft.Rtc.Collaboration.AudioVideo.WmaFileSource fileSource)
		{
			// conversation
			try
			{
				// stop
				if (null != fileSource)
				{
					// remove source
					fileSource.Close();
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Stop player
		/// </summary>
		/// <param name="recorder"></param>
		public void Stop(Microsoft.Rtc.Collaboration.AudioVideo.Player audioVideoPlayer)
		{
			// conversation
			try
			{
				// stop
				if (null != audioVideoPlayer)
				{
					// remove source
					audioVideoPlayer.RemoveSource();

					// stop
					if (audioVideoPlayer.State != Microsoft.Rtc.Collaboration.AudioVideo.PlayerState.Stopped)
					{
						audioVideoPlayer.Stop();
					}
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Detach flow
		/// </summary>
		/// <param name="conversationContextChannel"></param>
		/// <param name="asyncResultMethod"></param>
		public void DetachFlow(Microsoft.Rtc.Collaboration.AudioVideo.ToneController toneControler)
		{
			// conversation
			try
			{
				// check channel availale
				if (null != toneControler)
				{
					// check provided method
					toneControler.DetachFlow();
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Stop recorder
		/// </summary>
		/// <param name="recorder"></param>
		public void Stop(Microsoft.Rtc.Collaboration.AudioVideo.Recorder recorder)
		{
			// conversation
			try
			{
				// stop
				if (null != recorder && recorder.State != Microsoft.Rtc.Collaboration.AudioVideo.RecorderState.Stopped)
				{
					// stop
					recorder.Stop();
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateConversation(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateConversation", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.Conversation conversation = (Microsoft.Rtc.Collaboration.Conversation)ar.AsyncState; 

				// check
				conversation.EndTerminate(ar);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateConference(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateConversation", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.Conversation conversation = (Microsoft.Rtc.Collaboration.Conversation)ar.AsyncState;

				// end conference
				conversation.ConferenceSession.EndTerminateConference(ar);

				// terminate
				if (conversation.State != Microsoft.Rtc.Collaboration.ConversationState.Terminated)
				{
					// terminate conversation
					conversation.BeginTerminate(EndTerminateConversation, conversation);
				}
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateInstantMessagingCall(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateInstantMessagingCall", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.InstantMessagingCall instantMessagingCall = (Microsoft.Rtc.Collaboration.InstantMessagingCall)ar.AsyncState;

				// check
				instantMessagingCall.EndTerminate(ar);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateAudioVideoCall(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateAudioVideoCall", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.AudioVideo.AudioVideoCall audioVideoCall = (Microsoft.Rtc.Collaboration.AudioVideo.AudioVideoCall)ar.AsyncState;

				// check
				audioVideoCall.EndTerminate(ar);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateConversationContextChannel(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateConversationContextChannel", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.ConversationContextChannel conversationContextChannel = (Microsoft.Rtc.Collaboration.ConversationContextChannel)ar.AsyncState;

				// check
				conversationContextChannel.EndTerminate(ar);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		/// <summary>
		/// Terminate complete
		/// </summary>
		/// <param name="ar"></param>
		private void EndTerminateBackToBackCall(System.IAsyncResult ar)
		{
			// log
			EFS.EventLog.Log.LogInfo("EndTerminateConversationContextChannel", this);

			try
			{
				// cast
				Microsoft.Rtc.Collaboration.BackToBackCall b2bCall = (Microsoft.Rtc.Collaboration.BackToBackCall)ar.AsyncState;

				// check
				b2bCall.EndTerminate(ar);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion
	}
}

